package com.example.config;

import com.example.common.Result;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

/**
 * 统一响应体处理增强器
 * 作用：拦截所有Controller方法的返回值，进行统一封装
 */
@RestControllerAdvice // 组合注解：@ControllerAdvice + @ResponseBody
public class GlobalResponseAdvice implements ResponseBodyAdvice<Object> {

    /**
     * 判断是否支持对该处理器进行增强
     */
    @Override
    public boolean supports(MethodParameter returnType,
                            Class<? extends HttpMessageConverter<?>> converterType) {
        // 获取控制器方法所在的类
        Class<?> declaringClass = returnType.getDeclaringClass();

        // 排除Spring的一些内置端点（如Actuator监控端点）
        if (declaringClass.getName().contains("org.springframework.boot.actuate")) {
            return false;
        }

        // 排除本身就是Result类型的返回，避免重复包装
        if (returnType.getParameterType().equals(Result.class)) {
            return false;
        }

        // 其他情况都进行统一包装
        return true;
    }

    /**
     * 在响应体写入前的处理逻辑
     */
    @Override
    public Object beforeBodyWrite(Object body,
                                  MethodParameter returnType,
                                  MediaType selectedContentType,
                                  Class<? extends HttpMessageConverter<?>> selectedConverterType,
                                  ServerHttpRequest request,
                                  ServerHttpResponse response) {

        // 情况1：处理void返回类型
        if (body == null && returnType.getParameterType().equals(void.class)) {
            return Result.success(); // 返回无数据的成功响应
        }

        // 情况2：如果body已经是Result类型，直接返回
        if (body instanceof Result) {
            return body;
        }

        // 情况3：特殊处理String类型的返回值
        if (body instanceof String) {
            // String类型需要特殊处理，因为StringHttpMessageConverter要求输入必须是String类型
            ObjectMapper objectMapper = new ObjectMapper();
            try {
                // 将原始String包装成Result对象，并序列化成JSON字符串
                Result<String> result = Result.success((String) body);
                return objectMapper.writeValueAsString(result);
            } catch (JsonProcessingException e) {
                // 如果JSON序列化失败，返回错误信息
                throw new RuntimeException("JSON转换失败", e);
            }
        }

        // 情况4：普通情况 - 将原始body包装成Result格式
        return Result.success(body);
    }
}